# -*- coding: utf-8 -*-

# File Name： import_module
# Description :
# Author : ''
# create_date： 2022/5/30
# Change Activity:
"""
用于动态导入python模块和读取py格式配置文件
"""

import ast
import sys
from importlib import import_module

from .path import get_absolute_project_path, join_path, assert_file_exist, split_path, get_file_name


def validate_py_syntax(filename):
    """
    校验python语法合规,如果不合规 raise exception.

    Args:
        filename: py文件路径

    Returns:

    """
    with open(filename, 'r', encoding='utf-8') as f:
        # Setting encoding explicitly to resolve coding issue on windows
        content = f.read()
    try:
        ast.parse(content)
    except SyntaxError as e:
        raise SyntaxError(f'There are syntax errors in config file {filename}: {e}')


def import_py_config_file(py_relative_path, project_path=None) -> dict:
    """
    导入py配置文件

    Args:
        py_relative_path: py文件相对于项目路径的相对路径
        project_path: 项目绝对路径

    Returns:
        配置dict
    """

    if project_path is None:
        project_path = get_absolute_project_path()
    abs_py_path = join_path(project_path, py_relative_path)
    assert_file_exist(abs_py_path)
    dir_path, file_name = split_path(path=abs_py_path)
    sys.path.insert(0, dir_path)
    validate_py_syntax(abs_py_path)
    temp_module_name = get_file_name(file_name)
    mod = import_module(temp_module_name)
    sys.path.pop(0)
    cfg_dict = {
        name: value
        for name, value in mod.__dict__.items()
        if not name.startswith('__')
    }
    delete_imported_module(temp_module_name)
    return cfg_dict


def import_py_module(py_relative_dir, project_path=None):
    """
      导入py模块

      Args:
          py_relative_dir: py文件相对于项目路径的相对路径
          project_path: 项目绝对路径

      Returns:
          对应模块
      """
    if project_path is None:
        project_path = get_absolute_project_path()
    if project_path not in sys.path:
        sys.path.insert(0, project_path)
    py_relative_dir = py_relative_dir.replace('.py', '').replace("\\", '.').replace("/", '.')
    module = import_module(py_relative_dir)
    return module


def delete_imported_module(module_name):
    """
    删除已导入的模块

    Args:
        module_name: 模块名

    """

    del sys.modules[module_name]
